package com.seer.auto.dao;

import com.seer.auto.entity.EntityManager;
import com.seer.auto.utils.ClassUtils;
import com.seer.auto.utils.Global;
import java.util.HashMap;
import java.util.Map;
import javassist.CannotCompileException;
import javassist.NotFoundException;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Data
@Component
public class DaoManager {

    private String packageName = "com.seer.auto.dao.impl";

    private String implName = "Template";

    private Map<String, AbstractDao> daos = new HashMap<>();

    private Object lock = new Object();

    @Resource(name = "MyJdbcTemplate")
    private JdbcTemplate template;

    @Autowired
    private EntityManager entityManager;

    @PostConstruct
    public void regTemplate() {
        Global.register(template);
    }

    public String implName(String name) {
        return ClassUtils.className(name) + implName;
    }

    public <T> AbstractDao<T> load(String name)
        throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException {
        AbstractDao<T> dao = daos.get(name);
        if (null == dao) {
            synchronized (lock) {
                if (null == dao) {
                    final Class<?> dClass = ClassUtils.newSQLTemplate(
                        StringUtils.joinWith(".", packageName, implName(name)),
                        entityManager.getMeta(name));
                    dao = (AbstractDao) dClass.newInstance();
                    daos.put(name, dao);
                }
            }
        }
        return dao;
    }
}
